;File Game.lisp
;Abstract: 
;	-Creates a random level
;	-Prompt for and handle user input during gameplay
;	-Ends the game when the number of remaining swaps reaches 0
;	-create function: Play()

; Last Updated: 10/21/12 3:08pm by Michael
;	-Initial creation, created Create-Level function
; Last Updated: 10/21/12 4:38pm by Michael
;       -Created *score* and *swapcount* variables, as well as the functions to alter them
;       -Created the Swap and Swap-v functions to swap two elements + check if swappable.
;           However, still not completed yet.
;Updated: 11/10/12 5:29pm by Michael
;       -Fixed the Swap/Swap-v functions- they are now working correctly
;   To-Do: finalize the Swap function to implement the other functions (actual swapping of elements + match checking + removing)
;Updated: 11/11/12 7:16pm by Michael
;        -Fixed some text formatting. Updated the Swap and Play functions to implement the Check-For-Matches function

;(load "level_drawer.lisp")
;(load "main.lisp")
;(load "match_checker.lisp")
;(load "match_handler.lisp")

;_________________Variable Definition_____________________________
(defvar *variation* '5) ;how many variations there will be in shapes
(defvar *col* '5) ;number of columns
(defvar *row* '5) ;number of rows
(defvar *score* '0) ;score
(defvar *swapCount* '100); Remaining swap counts left
;__________________________________________________________________

;________________Main Function Calls_________________________
;Swap: checks if two elements are swappable (next to each other)
;   - (Swap '((c1 r1)(c2 r2))) -> T or nil
;
;Create-Level: creates a randomized level of colxrow based on variables
;   - (Create-Level) -> ((_ _ _..)(_ _ _..)(_ _ _..)..)

;____________________________________________________________

(defun score-u (x) ;Adds points to score
  (setf *score* (+ *score* x))
)

(defun swap-r () ;Lowers swap count by 1
  (setf *swapCount* (- *swapCount* 1))
)
(defun swap-i () ;increase swapcount by 1
  (setf *swapCount* (+ *swapCount* 1))
)

(defun num-r () ;Generates a random number from 1 to variation (inclusive)
  (+ (random *variation*) 1)
)

(defun Create-Col (&optional (count *row*)) ;Creates a list -> a column
  (if (eql count 0) nil
    (cons (num-r) (Create-Col (- count 1)))
    )
)

(defun Create-Level (&optional (count *col*)) ;Creates a list of list -> level
  (if (eql count 0) nil
    (cons (Create-Col) (Create-Level (- count 1)))
    )
)

(defun swap (level input) ;input should be ((r1 c1) (r2 c2))
  (let ((e1 (car input)) (e2 (car (cdr input))))
    (if (swap-v e1 e2 ) (progn (swap-r) (setf newLvl (Check-For-Matches level (car e1) (cadr e1) (car e2) (cadr e2))))
      (progn (format t "~2%Invalid move: Two pieces are not next to each other~2%") newLvl)
    ); if they are swappable -> run Match_Checker functions -> Match_Handler functions(?) if necessary
    
   )
)


(defun swap-v (e1 e2) ;checks to see if e1 and e2 are touching
  (let (valid)
    (if (eql (car e1) (car e2)) ;if both are same columns, then
        (if (or (eql (car (cdr e1)) (+ 1 (car (cdr e2)))) (eql (car (cdr e1)) (- (car (cdr e2)) 1))) (setf valid T) (setf valid nil)) ;if row pos are correct.
      (if (or (eql (car e1) (+ (car e2) 1)) (eql (car e1) (- (car e2) 1))) ;otherwise if not... check if car e1 and e2 are one apart. if so, then check the cdr
          (if (eql (car (cdr e1)) (car (cdr e2))) (setf valid T) (setf valid nil)) (setf valid nil)
       ) 
     )
    valid ;returns if the two elements are next to each other or not
  )
)


(defun prompt (level) ;initially prompts user if they would like to do a move
  (progn (format t "~2%") (princ (Get-Level-String level)) (format t "~2%Score: ~A~%Swaps Remaining: ~A~%To exit, type x~2%" *score* *swapCount*)
   )
)

(defun size-set (col row)
  (setf *col* col)
  (setf *row* row)
)


(defun Play (col row) ;x and y will be integers derived from the Menu/Main() function
  (size-set col row)
  (let ((level (Check-for-Matches (Create-Level) 1 1 1 1))) ;sets level to a new randomized level ;Might need to remove the check-for-matches
      (setf *score* 0 *swapCount* 20)
      (do ((input1 NIL) (input2 NIL))
           ((or (eql input1 'x) (eql input2 'x)) (format t "Thanks for playing")) (prompt level)
           (format t "~%Enter first element in the form (c r): ")
           (setf input1 (get-input))
           (if (eql input1 'x) (return))
           (format t "~%Enter second element in the form (c r): ")
           (setf input2 (get-input))
           (if (eql input2 'x) (return))
           (format t "~%Swapping elements ~A and ~A" input1 input2)
           (setf level (swap level (list input1 input2)))   ;swaps the two elements via the swap function
       )
      "Thanks for playing"
   )
)
